package com.feilong.edgeAI.update;

import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;

import android.Manifest;
import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.RemoteException;
import android.util.Log;

import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import androidx.core.content.FileProvider;

import com.feilong.edgeAI.BuildConfig;
import com.feilong.edgeAI.R;
import com.feilong.edgeAI.model.DownloadProgress;
import com.feilong.edgeAI.model.RequestInstallApk;
import com.feilong.edgeAI.model.ShowDownLoadDialog;
import com.feilong.edgeAI.model.StartInstallApk;
import com.feilong.edgeAI.service.FeiLongService;
import com.feilong.edgeAI.ui.HomeActivity;
import com.feilong.edgeAI.utils.NotificationUtils;
import com.hjq.permissions.OnPermission;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;

import pub.devrel.easypermissions.EasyPermissions;

public class ApkUpdateService extends IntentService {
    private static final int BUFFER_SIZE = 10 * 1024; // 8k ~ 32K
    private static final String TAG = "ApkUpdateService";
    private String channelId="update";
    private NotificationManager mNotifyManager;
    private
    NotificationCompat.Builder mBuilder;
    public static final String APK_DOWNLOAD_URL = "url";
    public static final String APK_UPDATE_CONTENT = "updateMessage";
    public static final String APK_VERSION_CODE = "versionCode";
    public static final String APK_VERSION_NAME = "versionName";
    public ApkUpdateService() {
        super("ApkUpdateService");
    }
    private static final String CHANNEL_ID = "ApkUpdateService";
    private static final int NOTIFICATION_ID = 102;
    private File apkFile;
    @RequiresApi(api = Build.VERSION_CODES.O)
    private void startForeground() {
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this);
        }
        // Create Notification Channel
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel serviceChannel = new NotificationChannel(
                    CHANNEL_ID,
                    "feilong",
                    NotificationManager.IMPORTANCE_DEFAULT
            );
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(serviceChannel);
        }

        // Create Notification
        Notification notification = new Notification.Builder(this, CHANNEL_ID)
                .setContentTitle("Foreground Service")
                .setContentText("Service is running...")
                .build();

        // Start Foreground Service with notification
        startForeground(NOTIFICATION_ID, notification);
    }
    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    protected void onHandleIntent(Intent intent) {
        startForeground();
        String urlStr = intent.getStringExtra(APK_DOWNLOAD_URL);
        Log.d(TAG, "onHandleIntent: " + urlStr);
        InputStream in = null;
        FileOutputStream out = null;
        try {
            URL url = new URL(urlStr);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.setDoOutput(false);
            urlConnection.setConnectTimeout(10 * 1000);
            urlConnection.setReadTimeout(10 * 1000);
//			urlConnection.setRequestProperty("Connection", "Keep-Alive");
//			urlConnection.setRequestProperty("Charset", "UTF-8");
//			urlConnection.setRequestProperty("Accept-Encoding", "gzip, deflate");

            urlConnection.connect();
            long bytetotal = urlConnection.getContentLength();
            long bytesum = 0;
            int byteread = 0;
            in = urlConnection.getInputStream();
            File dir = StorageUtils.getCacheDirectory(this);
            String apkName = urlStr.substring(urlStr.lastIndexOf("/") + 1, urlStr.length());
            apkFile = new File(dir, apkName);
            out = new FileOutputStream(apkFile);
            byte[] buffer = new byte[BUFFER_SIZE];

            int oldProgress = 0;
            EventBus.getDefault().post(new ShowDownLoadDialog(true,getString(R.string.feilong_downloading)));
            while ((byteread = in.read(buffer)) != -1) {
                bytesum += byteread;
                out.write(buffer, 0, byteread);

                int progress = (int) (bytesum * 100L / bytetotal);
                // 如果进度与之前进度相等，则不更新，如果更新太频繁，否则会造成界面卡顿
                if (progress != oldProgress) {
                    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
                        updateProgress(progress);
                    }else{
                        EventBus.getDefault().post(new DownloadProgress(progress));
                        NotificationUtils.showNotification(getString(getApplicationInfo().labelRes),this.getString(R.string.download_progress, progress),0,channelId,progress,100);
                    }
                }
                oldProgress = progress;
            }
            EventBus.getDefault().post(new ShowDownLoadDialog(false,getString(R.string.feilong_downloading)));
            autoInstallApk(this,apkFile);
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
//                Notification noti = mBuilder.build();
//                noti.flags = Notification.FLAG_AUTO_CANCEL;
//                mNotifyManager.notify(0, noti);
            }else{
//                NotificationUtils.showNotification(getString(getApplicationInfo().labelRes),"点击安装",0,channelId);
                NotificationUtils.cancleNotification(0);
            }

        } catch (Exception e) {
            Log.e(TAG, "download apk file error", e);
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(StartInstallApk state) throws RemoteException {
        autoInstallApk(this,apkFile);
    }
    private void requestPermissions() {
        String[] perms = {Manifest.permission.REQUEST_INSTALL_PACKAGES};
        if (EasyPermissions.hasPermissions(this, perms)) {
            autoInstallApk(this,apkFile);
        }else{
            EventBus.getDefault().post(new RequestInstallApk());
        }
    }

    private void autoInstallApk(Context context,File file) {
//    public static void autoInstallApk(Context context,File file) {
        try {
            String[] args2 = {"chmod", "777", file.getAbsolutePath()};
            Runtime.getRuntime().exec(args2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String path = file.getAbsolutePath();
        long len = file.length();
        Log.d(TAG, "autoInstallApk: "+path);
        Log.d(TAG, "len: "+len);
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
        try{
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
                intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
            } else {
                // 声明需要的临时的权限
                // 第二个参数，即第一步中配置的authorities
                Uri contentUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID+".FileProvider", file);
                intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
            }
            context.startActivity(intent);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    private void updateProgress(int progress) {
        //"正在下载:" + progress + "%"
        mBuilder.setContentText(this.getString(R.string.download_progress, progress)).setProgress(100, progress, false);
        //setContentInent如果不设置在4.0+上没有问题，在4.0以下会报异常
        PendingIntent pendingintent = PendingIntent.getActivity(this, 0, new Intent(), PendingIntent.FLAG_CANCEL_CURRENT);
        mBuilder.setContentIntent(pendingintent);
        mNotifyManager.notify(0, mBuilder.build());
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this);
        }
    }
}
